package com.ly.emp.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.core.bean.R;
import com.ly.common.core.bean.dto.CommonBatchUpdateDTO;
import com.ly.common.core.constant.BaseConstant;
import com.ly.common.core.exception.ServiceException;
import com.ly.common.core.utils.DateUtils;
import com.ly.emp.bean.vo.BasePeriodTree;
import com.ly.emp.entity.EpmBasePeriod;
import com.ly.emp.mapper.EpmBasePeriodMapper;
import com.ly.emp.service.IEpmBasePeriodService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 考核周期-impl
 *
 * @author luoyun
 * @Date: 2025-05-13
 */
@Service
public class EpmBasePeriodServiceImpl extends ServiceImpl<EpmBasePeriodMapper, EpmBasePeriod> implements IEpmBasePeriodService {

    @Override
    public R getId(String id) {
        EpmBasePeriod entity = this.getById(id);
        if (entity == null) {
            return R.fail("未找到对应数据");
        }
        return R.ok(entity);
    }

    @Override
    public R getPage(EpmBasePeriod entity, Page<EpmBasePeriod> page) {
        IPage<EpmBasePeriod> pageList = this.page(
                page,
                new LambdaQueryWrapper<EpmBasePeriod>()
                        .like(StrUtil.isNotEmpty(entity.getPeriodName()), EpmBasePeriod::getPeriodName, entity.getPeriodName())
                        .like(StrUtil.isNotEmpty(entity.getPeriodCode()), EpmBasePeriod::getPeriodCode, entity.getPeriodCode())
                        .eq(StrUtil.isNotEmpty(entity.getPeriodType()), EpmBasePeriod::getPeriodType, entity.getPeriodType())
                        .orderByAsc(EpmBasePeriod::getPeriodCode)
                        .orderByAsc(EpmBasePeriod::getDisplayOrder)
        );
        return R.ok(pageList);
    }

    @Override
    public R add(EpmBasePeriod entity) {
        boolean flag = false;
        String periodcode = entity.getPeriodCode();
        String remark = entity.getRemark();
        // 如果周期编码为空返回false
        if (StrUtil.isBlank(periodcode)) {
            throw new ServiceException("年度值不能为空");
        }
        // 周期编码不为空，且为四位
        if (StrUtil.isNotBlank(periodcode) && periodcode.length() == 4) {
            EpmBasePeriod periodEntity = this.getOne(
                    new LambdaQueryWrapper<EpmBasePeriod>()
                            .eq(EpmBasePeriod::getPeriodCode, periodcode)
                    , false);
            // 考核周期存在返回false
            if (periodEntity != null) {
                throw new ServiceException("考核周期已存在");
            }
            // 初始化年度、半年、季度、月度数据
            List<EpmBasePeriod> list = new ArrayList<EpmBasePeriod>();
            this.insertYearRecord(periodcode, remark, list);
            this.insertHalfYearRecord(periodcode, remark, list);
            this.insertQuarterRecord(periodcode, remark, list);
            this.insertMonthRecord(periodcode, remark, list);
            flag = this.saveBatch(list);
        }
        return flag ? R.ok(true, "创建成功") : R.fail("创建失败");
    }

    @Override
    public R edit(EpmBasePeriod entity) {
        boolean flag = this.updateById(entity);
        return flag ? R.ok(true, "修改成功") : R.fail("修改失败");
    }

    @Override
    public R delete(String id) {
        boolean flag = this.removeById(id);
        return flag ? R.ok(true, "删除成功") : R.fail("删除失败");
    }

    @Override
    public R deleteBatch(String ids) {
        boolean flag = this.removeByIds(Arrays.asList(ids.split(",")));
        return flag ? R.ok(true, "批量删除成功") : R.fail("批量删除失败");
    }

    @Override
    public R updateBatch(CommonBatchUpdateDTO<EpmBasePeriod> dto) {
        List<EpmBasePeriod> datas = dto.getDatas();
        boolean flag = this.saveOrUpdateBatch(datas);
        return flag ? R.ok(true, "批量修改成功") : R.fail("批量修改失败");
    }

    @Override
    public List<BasePeriodTree> periodTree(String type) {
        List<BasePeriodTree> list = new ArrayList<>();
        if ("year".equals(type) || "yearM".equals(type) || "yearQ".equals(type) || "yearQuarter".equals(type)) {
            List<EpmBasePeriod> yearList = this.list(
                    new LambdaQueryWrapper<EpmBasePeriod>()
                            .eq(EpmBasePeriod::getParentCode, "-1")
                            .orderByDesc(EpmBasePeriod::getPeriodCode)
            );
            if (CollUtil.isNotEmpty(yearList)) {
                yearList.stream().forEach(n -> list.add(new BasePeriodTree(n.getPeriodCode(), n.getPeriodName())));
            }
            if (!"year".equals(type)) {
                for (BasePeriodTree basePeriod : list) {
                    String periodCode = basePeriod.getPeriodCode();
                    List<BasePeriodTree> mList = new ArrayList<>();
                    List<EpmBasePeriod> periodMList = this.getMQ(periodCode, type);
                    for (EpmBasePeriod period : periodMList) {
                        BasePeriodTree basePeriodTree = new BasePeriodTree();
                        basePeriodTree.setPeriodCode(period.getPeriodCode());
                        basePeriodTree.setPeriodName(period.getPeriodName());
                        mList.add(basePeriodTree);
                    }
                    basePeriod.setChild(mList);
                }
            }
        }
        return list;
    }

    public List<EpmBasePeriod> getMQ(String periodCode, String type) {
        LambdaQueryWrapper<EpmBasePeriod> queryWrapper = new LambdaQueryWrapper<>();
        if ("yearM".equals(type)) {
            queryWrapper.eq(EpmBasePeriod::getParentCode, periodCode);
            queryWrapper.eq(EpmBasePeriod::getPeriodType, "4");
        } else if ("yearQ".equals(type)) {
            queryWrapper.eq(EpmBasePeriod::getParentCode, periodCode);
            queryWrapper.and(wq -> wq
                    .eq(EpmBasePeriod::getPeriodType, '3').or().eq(EpmBasePeriod::getPeriodType, '4')
            );
        } else if ("yearQuarter".equals(type)) {
            // 季度
            queryWrapper.eq(EpmBasePeriod::getParentCode, periodCode);
            queryWrapper.eq(EpmBasePeriod::getPeriodType, "3");
        }
        return this.list(queryWrapper);
    }

    public void insertYearRecord(String year, String remark, List<EpmBasePeriod> list) {
        // 年度开始日期
        String yearBeginDate = year + "-01-01";
        // 年度结束日期
        String yearEndDate = year + "-12-31";
        EpmBasePeriod basePeriodEntity = new EpmBasePeriod();
        basePeriodEntity.setPeriodCode(year);
        basePeriodEntity.setPeriodName(year + "年");
        basePeriodEntity.setParentCode("-1");
        basePeriodEntity.setBeginDate(yearBeginDate);
        basePeriodEntity.setEndDate(yearEndDate);
        // 类型为"年度"
        basePeriodEntity.setPeriodType(BaseConstant.PERIODTYPE_Y);
        basePeriodEntity.setRemark(remark);
        basePeriodEntity.setLevelCode("-1");
        list.add(basePeriodEntity);
    }

    /**
     * 初始化插入上下半年周期记录
     */
    public void insertHalfYearRecord(String year, String remark, List<EpmBasePeriod> list) {
        // 上半年度开始日期
        String yOnBeginDate = year + "-01-01";
        // 上半年度结束日期
        String yOnEndDate = year + "-06-30";
        EpmBasePeriod basePeriodOnEntity = new EpmBasePeriod();
        basePeriodOnEntity.setPeriodCode(year + "Y1");
        basePeriodOnEntity.setPeriodName(year + "上半年");
        basePeriodOnEntity.setParentCode(year);
        basePeriodOnEntity.setBeginDate(yOnBeginDate);
        basePeriodOnEntity.setEndDate(yOnEndDate);
        // 类型为"半年"度
        basePeriodOnEntity.setPeriodType(BaseConstant.PERIODTYPE_HY);
        basePeriodOnEntity.setRemark(StrUtil.EMPTY);
        basePeriodOnEntity.setLevelCode(year);
        list.add(basePeriodOnEntity);
        // 下半年度开始日期
        String yUpBeginDate = year + "-07-01";
        // 下半年度结束日期
        String yUpEndDate = year + "-12-31";
        // 插入下半年
        EpmBasePeriod basePeriodUpEntity = new EpmBasePeriod();
        basePeriodUpEntity.setPeriodCode(year + "Y2");
        basePeriodUpEntity.setPeriodName(year + "下半年");
        basePeriodUpEntity.setParentCode(year);
        basePeriodUpEntity.setBeginDate(yUpBeginDate);
        basePeriodUpEntity.setEndDate(yUpEndDate);
        // 类型为"半年"度
        basePeriodUpEntity.setPeriodType(BaseConstant.PERIODTYPE_HY);
        basePeriodUpEntity.setRemark(StrUtil.EMPTY);
        basePeriodUpEntity.setLevelCode(year);
        list.add(basePeriodUpEntity);
    }

    /**
     * @核心介绍: 初始化插入季度周期记录
     */
    public void insertQuarterRecord(String year, String remark, List<EpmBasePeriod> list) {
        // 季度起始月
        String qStartMonth = "";
        // 季度终止月
        String qEndMonth = "";
        String levelCode = "";
        for (int i = 0; i < 4; i++) {
            if (i < 2) {
                levelCode = year + "Y1";
            } else {
                levelCode = year + "Y2";
            }
            if (3 * i + 1 > 9) {
                qStartMonth = Integer.toString(3 * i + 1);
                qEndMonth = Integer.toString((i + 1) * 3);
            } else {
                qStartMonth = "0" + Integer.toString(3 * i + 1);
                qEndMonth = "0" + Integer.toString(3 * (i + 1));
            }
            // 季度开始日期
            String monthBeginDate = year + "-" + qStartMonth + "-01";
            // 季度结束日期
            String monthEndDate = year + "-" + qEndMonth + "-"
                    + Integer.toString(DateUtils.getLastdayOfMonth(Integer.parseInt(year), 3 * (i + 1)));
            // 插入季度周期
            EpmBasePeriod basePeriodEntity = new EpmBasePeriod();
            basePeriodEntity.setPeriodCode(year + "Q" + Integer.toString(i + 1));
            basePeriodEntity.setPeriodName(year + "年第" + Integer.toString(i + 1) + "季度");
            basePeriodEntity.setParentCode(year);
            basePeriodEntity.setBeginDate(monthBeginDate);
            basePeriodEntity.setEndDate(monthEndDate);
            // 类型为季度
            basePeriodEntity.setPeriodType(BaseConstant.PERIODTYPE_Q);
            basePeriodEntity.setRemark(StrUtil.EMPTY);
            basePeriodEntity.setLevelCode(levelCode);
            list.add(basePeriodEntity);
        }
    }

    /**
     * @核心介绍: 初始化插入月周期记录
     */
    public void insertMonthRecord(String year, String remark, List<EpmBasePeriod> list) {
        // 初始化插入月周期记录
        String levelCode = "";
        String month = "";
        for (int i = 1; i < 13; i++) {
            if (i > 9) {
                month = Integer.toString(i);
                levelCode = year + "Q4";
            } else {
                month = "0" + Integer.toString(i);
                if (i < 4) {
                    levelCode = year + "Q1";
                } else if (i < 7) {
                    levelCode = year + "Q2";
                } else {
                    levelCode = year + "Q3";
                }
            }
            // 月开始日期
            String monthBeginDate = year + "-" + month + "-01";
            // 月结束日期
            String monthEndDate = year + "-" + month + "-"
                    + Integer.toString(DateUtils.getLastdayOfMonth(Integer.parseInt(year), i));
            // 插入月周期
            EpmBasePeriod basePeriodEntity = new EpmBasePeriod();
            basePeriodEntity.setPeriodCode(year + month);
            basePeriodEntity.setPeriodName(year + "年" + Integer.toString(i) + "月");
            basePeriodEntity.setParentCode(year);
            basePeriodEntity.setBeginDate(monthBeginDate);
            basePeriodEntity.setEndDate(monthEndDate);
            // 类型为月度
            basePeriodEntity.setPeriodType(BaseConstant.PERIODTYPE_M);
            basePeriodEntity.setRemark(StrUtil.EMPTY);
            basePeriodEntity.setLevelCode(levelCode);
            list.add(basePeriodEntity);
        }
    }
}
